package com.cardone.common.function;

import com.cardone.common.util.*;
import com.cardone.context.function.*;
import lombok.extern.slf4j.*;
import org.apache.commons.compress.archivers.zip.*;
import org.apache.commons.io.*;
import org.apache.commons.lang.StringUtils;

import java.io.*;
import java.security.*;

@Slf4j
public class CreateZipFileFunction implements Execution2Function<String, String, String> {
    @Override
    public String execution(final String filename, final String password) {
        final String zipFullPath = FilenameUtils.getFullPath(filename);

        final String zipBaseName = FilenameUtils.getBaseName(filename);

        final String zipExtension = "zip";

        final String zipFilename = StringUtils.join(new String[]{zipFullPath, zipBaseName, ".", zipExtension});

        final String zipTempFilename = StringUtils.join(new String[]{zipFullPath, zipBaseName, "_temp.", zipExtension});

        final String name = FilenameUtils.getName(filename);

        final int bufferLen = 1024 * 1024;

        try (FileInputStream fis = new FileInputStream(filename)) {
            try (InputStream is = new BufferedInputStream(fis, bufferLen)) {
                try (FileOutputStream fos = new FileOutputStream(zipTempFilename)) {
                    try (BufferedOutputStream bos = new BufferedOutputStream(fos, bufferLen)) {
                        try (ZipArchiveOutputStream out = new ZipArchiveOutputStream(bos)) {
                            final ZipArchiveEntry entry = new ZipArchiveEntry(name);

                            out.putArchiveEntry(entry);

                            IOUtils.copy(is, out);

                            out.flush();
                        }
                    }
                }
            }
        } catch (java.io.IOException e) {
            throw new com.cardone.context.DictionaryException(e.getMessage(), e);
        }

        try {
            CipherUtils.encrypt(zipTempFilename, zipFilename, password);
        } catch (GeneralSecurityException | IOException e) {
            throw new com.cardone.context.DictionaryException(e.getMessage(), e);
        } finally {
            FileUtils.deleteQuietly(new File(zipTempFilename));
        }

        return zipFilename;
    }
}
